// ============================================================================
// 应用程序核心类
// ============================================================================

import { app, BrowserWindow } from 'electron'
import { Container } from './container'
import { ErrorHandler } from './error-handler'
import { EventBus } from './event-bus'
import { LoggerService } from './logger-service'
import { WindowManager } from '../window'
import { ConfigManager } from '../config/config-manager'
import { IPCManager } from './ipc-manager'
import { RabbitMQManager } from './rabbitmq-manager'
import { TaskScheduler, initializeScheduler } from './scheduler'
import { TaskManager } from '../tasks/task-manager'
import { WeiboWorkflowService } from '../services/weibo-workflow-service'
import { MonitoringService } from '../services/monitoring-service'
import { BrowserPoolManager, createConfig } from '@roasmax/browser'
import { AppStartEvent, AppShutdownEvent } from '../../shared/types'
import { closeDataSource, initializeDataSource } from '../storage/data-source'

/**
 * 应用程序主类
 * 负责应用的生命周期管理和核心服务的初始化
 */
export class Application {
  private container: Container
  private errorHandler: ErrorHandler
  private eventBus: EventBus
  private logger: LoggerService
  private browserManager: BrowserPoolManager | null = null
  private isInitialized = false
  private isShuttingDown = false

  constructor() {
    this.container = new Container()
    this.errorHandler = new ErrorHandler()
    this.eventBus = new EventBus()
    this.logger = new LoggerService()

    this.setupErrorHandling()
    this.setupEventHandlers()
    this.registerServices()
  }

  /**
   * 初始化应用程序
   */
  async initialize(): Promise<void> {
    if (this.isInitialized) {
      throw new Error('Application is already initialized')
    }

    try {
      this.logger.info('Application initialization started')

      // 发送应用启动事件
      this.eventBus.emit<AppStartEvent>({
        type: 'app:start',
        timestamp: new Date(),
        level: 'info',
        version: app.getVersion(),
        platform: process.platform
      })

      // 初始化核心服务
      await this.initializeServices()

      // 创建主窗口
      await this.createMainWindow()

      // 设置IPC通信（确保在所有服务初始化后）
      await this.setupIPC()

      this.isInitialized = true
      this.logger.info('Application initialization completed')

    } catch (error) {
      this.logger.error('Application initialization failed:', error)
      await this.handleInitializationError(error)
      throw error
    }
  }

  /**
   * 关闭应用程序
   */
  async shutdown(): Promise<void> {
    if (this.isShuttingDown) {
      return
    }

    this.isShuttingDown = true

    try {
      this.logger.info('Application shutdown started')

      // 发送应用关闭事件
      this.eventBus.emit<AppShutdownEvent>({
        type: 'app:shutdown',
        timestamp: new Date(),
        level: 'info',
        reason: 'user',
        uptime: process.uptime() * 1000
      })

      // 关闭所有服务
      await this.shutdownServices()

      this.logger.info('Application shutdown completed')

    } catch (error) {
      this.logger.error('Application shutdown failed:', error)
    }
  }

  /**
   * 获取服务容器
   */
  getContainer(): Container {
    return this.container
  }

  /**
   * 获取事件总线
   */
  getEventBus(): EventBus {
    return this.eventBus
  }

  /**
   * 注册核心服务
   */
  private registerServices(): void {
    // 注册单例服务
    this.container.registerSingleton('errorHandler', () => this.errorHandler)
    this.container.registerSingleton('eventBus', () => this.eventBus)
    this.container.registerSingleton('logger', () => this.logger)

    // 注册业务服务
    this.container.registerSingleton('windowManager', () => new WindowManager())

    // 数据库服务 - 支持 TypeORM 和传统数据库

    this.container.registerSingleton('configManager', () => new ConfigManager())
    this.container.registerSingleton('ipcManager', () => new IPCManager(this.container))
    this.container.registerSingleton('rabbitmqManager', () => RabbitMQManager.getInstance())
    this.container.registerSingleton('taskManager', () => new TaskManager())

    // 注册浏览器管理器工厂函数
    this.container.registerSingleton('browserManagerFactory', () => this.createBrowserManager.bind(this))
  }

  /**
   * 初始化服务
   */
  private async initializeServices(): Promise<void> {
    // 初始化日志服务
    await this.logger.initialize()

    // 数据库
    await initializeDataSource();

    // 初始化配置管理器
    const configManager = this.container.get<ConfigManager>('configManager')
    await configManager.initialize()

    // 初始化RabbitMQ管理器
    try {
      const rabbitmqManager = this.container.get<RabbitMQManager>('rabbitmqManager')
      await rabbitmqManager.initialize()
    } catch (error) {
      this.logger.warn('RabbitMQ初始化失败，将继续运行但不发送消息', error)
    }

    // 初始化任务调度器
    try {
      const scheduler = initializeScheduler({
        enabled: true,
        maxConcurrentJobs: 3,
        defaultInterval: 30 * 60 * 1000, // 30分钟
        retryAttempts: 3
      })

      this.container.registerInstance('scheduler', scheduler)
      await scheduler.start()

      // 初始化工作流服务
      const rabbitmqManager = this.container.get<RabbitMQManager>('rabbitmqManager')
      const workflowService = WeiboWorkflowService.getInstance(
        scheduler,
        {
          maxConcurrentKeywords: 3,
          maxPagesPerKeyword: 5,
          requestDelay: 2000,
          retryAttempts: 3,
          batchSize: 10,
          enableMQ: true
        }
      )
      this.container.registerInstance('workflowService', workflowService)

      // 初始化监控服务
      const monitoringService = MonitoringService.getInstance(
        scheduler, workflowService, rabbitmqManager, {
        enabled: true,
        interval: 60 * 1000, // 1分钟
        alertThresholds: {
          memoryUsage: 512, // 512MB
          errorRate: 10, // 10%
          queueBacklog: 1000 // 1000条消息
        },
        retentionDays: 7
      }
      )
      this.container.registerInstance('monitoringService', monitoringService)
      await monitoringService.start()

      // 初始化浏览器管理器
      this.initializeBrowserManager()

      this.logger.info('任务调度器、工作流服务和监控服务初始化成功')
    } catch (error) {
      this.logger.warn('服务初始化失败', error)
    }
  }

  /**
   * 创建主窗口
   */
  private async createMainWindow(): Promise<void> {
    const windowManager = this.container.get<WindowManager>('windowManager')
    const mainWindow = windowManager.createMainWindow()

    // 将主窗口注册到容器中
    this.container.registerInstance('mainWindow', mainWindow)

    // 设置TaskManager的主窗口引用和浏览器管理器工厂
    const taskManager = this.container.get<TaskManager>('taskManager')
    taskManager.setMainWindow(mainWindow)
  }

  /**
   * 设置IPC通信
   */
  private async setupIPC(): Promise<void> {
    const ipcManager = this.container.get<IPCManager>('ipcManager')
    await ipcManager.initialize()
  }

  /**
   * 关闭服务
   */
  private async shutdownServices(): Promise<void> {
    try {
      // 停止监控服务
      if (this.container.has('monitoringService')) {
        try {
          const monitoringService = this.container.get<MonitoringService>('monitoringService')
          await monitoringService.stop()
        } catch (error) {
          this.logger.warn('停止监控服务失败', error)
        }
      } else {
        this.logger.debug('监控服务未注册，跳过停止')
      }

      // 停止任务调度器
      if (this.container.has('scheduler')) {
        try {
          const scheduler = this.container.get<TaskScheduler>('scheduler')
          await scheduler.stop()
        } catch (error) {
          this.logger.warn('停止任务调度器失败', error)
        }
      } else {
        this.logger.debug('任务调度器未注册，跳过停止')
      }

      // 关闭RabbitMQ连接
      if (this.container.has('rabbitmqManager')) {
        try {
          const rabbitmqManager = this.container.get<RabbitMQManager>('rabbitmqManager')
          await rabbitmqManager.close()
        } catch (error) {
          this.logger.warn('关闭RabbitMQ连接失败', error)
        }
      } else {
        this.logger.debug('RabbitMQ管理器未注册，跳过关闭')
      }

      // 清理浏览器管理器
      try {
        if (this.browserManager) {
          await this.browserManager.cleanup()
          this.browserManager = null
        }
      } catch (error) {
        this.logger.warn('清理浏览器管理器失败', error)
      }

      // 关闭数据源
      try {
        await closeDataSource()
      } catch (error) {
        this.logger.warn('关闭数据源失败', error)
      }

      // 关闭所有窗口
      if (this.container.has('windowManager')) {
        try {
          const windowManager = this.container.get<WindowManager>('windowManager')
          windowManager.closeAllWindows()
        } catch (error) {
          this.logger.warn('关闭窗口失败', error)
        }
      } else {
        this.logger.debug('窗口管理器未注册，跳过关闭')
      }

    } catch (error) {
      this.logger.error('Error during service shutdown:', error)
    }
  }

  /**
   * 设置错误处理
   */
  private setupErrorHandling(): void {
    // 处理未捕获的异常
    process.on('uncaughtException', (error) => {
      this.errorHandler.handleError(error, 'uncaughtException')
    })

    // 处理未处理的Promise拒绝
    process.on('unhandledRejection', (reason, promise) => {
      this.errorHandler.handleError(
        new Error(`Unhandled Promise Rejection: ${reason}`),
        'unhandledRejection',
        { context: { promise } }
      )
    })
  }

  /**
   * 设置应用事件处理
   */
  private setupEventHandlers(): void {
    // 当所有窗口关闭时退出应用（macOS除外）
    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })

    // 当应用激活时创建窗口（macOS）
    app.on('activate', () => {
      if (BrowserWindow.getAllWindows().length === 0) {
        const windowManager = this.container.get<WindowManager>('windowManager')
        windowManager.createMainWindow()
      }
    })

    // 应用即将退出
    app.on('before-quit', async () => {
      await this.shutdown()
    })

    // 处理第二个实例
    app.on('second-instance', () => {
      const mainWindow = this.container.get<BrowserWindow>('mainWindow')
      if (mainWindow && !mainWindow.isDestroyed()) {
        if (mainWindow.isMinimized()) mainWindow.restore()
        mainWindow.focus()
      }
    })
  }

  /**
   * 初始化浏览器管理器
   */
  private initializeBrowserManager(): void {
    try {
      const config = createConfig({
        browserPool: {
          maxInstances: 8,
          minInstances: 1,
          defaultHeadless: true,
          defaultTimeout: 30000
        },
        proxy: {
          enabled: false
        }
      })

      this.browserManager = new BrowserPoolManager(config)
      this.container.registerInstance('browserManager', this.browserManager)

      this.logger.info('浏览器管理器初始化成功', {
        maxInstances: config.browserPool.maxInstances,
        minInstances: config.browserPool.minInstances,
        headless: config.browserPool.defaultHeadless
      })
    } catch (error) {
      this.logger.error('浏览器管理器初始化失败', error)
    }
  }

  /**
   * 创建浏览器管理器实例（工厂方法）
   */
  createBrowserManager(): BrowserPoolManager {
    if (!this.browserManager) {
      this.initializeBrowserManager()
    }
    return this.browserManager!
  }

  /**
   * 获取浏览器管理器
   */
  getBrowserManager(): BrowserPoolManager | null {
    return this.browserManager
  }

  /**
   * 处理初始化错误
   */
  private async handleInitializationError(error: any): Promise<void> {
    this.errorHandler.handleError(error, 'initialization')

    // 如果初始化失败，退出应用
    setTimeout(() => {
      app.quit()
    }, 1000)
  }
}
